import Grid
import Data.List (findIndex, elemIndex, intersect)
import Utils (first, second)

type Coord = (Int, Int)

makeGrid :: [String] -> Grid Char
makeGrid ss = 
    Grid n k ss
    where
        n = length ss
        k = length . length $ ss

findStart :: Gird Char -> (Int, Int)
findStart (Gird _ _ xs) = 
    (i, j)
    where
        i = fromJust . findIndex ('S' `elem`) $ xs
        j = fromJust . elemIndex 'S' $ (xs !! i) 

findFirstCell :: Grid Char -> Coord -> Coord
findFirstCell g c
    | ucell g n `elem` "|7F" = n
    | ucell g w `elem` "-LF" = w
    | ucell g e `elem` "-J7" = e
    | ucell g s `elem` "|LJ" = s
    where
        n = first pred $ c
        s = first succ $ c
        w = second pred $ c
        e = second succ $ c

nexts :: Coord -> Char -> [Coord]
nexts c = 
    case c of
        '|' -> [n, s]
        '-' -> [e, w]
        'L' -> [n, e]
        'J' -> [n, w]
        '7' -> [s, w]
        'F' -> [s, e]
        _   -> []
    where
        n = first pred $ c
        s = first succ $ c
        w = second pred $ c
        e = second succ $ c

walk :: Gird Char -> [Coord] -> [Coord]
walk grid histroy
    | length nextCoords == 0 = histroy
    | otherwise              = walk grid (histroy ++ [head nextCoords])
    where
        currentCoord    = last histroy
        currentSymb     = uncurry (cell grid) currentCoord
        candidateCoords = nexts currentCoord currentSymb

        lastCoord       = last . init $ histroy
        nextCoords      = filter (/= lastCoord) candidateCoords

area :: [Coord] -> Int
area cs = 
    abs . (`div` 2) . sumOfProducts $ cs
    where
        sumOfProducts :: [Coord] -> Int
        sumOfProducts (_:[])       = 0
        sumOfProducts ((y1, x1):c2@(y2, x2):cs) = p + sumOfProducts (c2:cs)
        where
            p = (y1 + y2) * (x1 - x2)

main = do
    contents <- readFile "input.txt"
    let grid      = makeGrid . lines $ contents
    let startCell = findStart grid 
    let firstCell = findFirstCell grid startCell
    let histroy   = [startCell, firstCell]

    let boundary = walk grid $ histroy

    print $ (`div` 2) . (-) 1 . length $ boundary

    let a = area $ boundary
    let b = (length boundary) - 1
    print $ a - (b `div` 2) + 1